
#include "linux_def.h"
#include "core.h"
#include "event.h"

#define DEFAULT_CONNECTIONS	512

char *event_init(cycle_t *cycle);
int event_process_init(cycle_t *cycle);


static uintptr_t	timer_resolution;
sig_atomic_t	event_timer_alarm;


uintptr_t	event_flags;

static	uint32_t	connection_counter = 1;
uint32_t	*connection_counter_ptr = & connection_counter;

uint32_t	*accept_mutex_ptr;
shmtx_t		accept_mutex;
uintptr_t	use_accept_mutex;
uintptr_t	accept_events;
uintptr_t	accept_mutex_held;
uintptr_t	accept_mutex_held;
uintptr_t	accept_mutex_delay;
int	accept_disabled;


void timer_signal_handler(int signo)
{
	event_timer_alarm = 1;
		
	time_update(0, 0);
}

void process_events_and_timers(cycle_t *cycle)
{
	uintptr_t	flags = 0;
	uintptr_t	timer = 0, delta = 0;

	if (timer_resolution){
		timer	= -1;
		flags	= 0;
	}else{	
		timer	= event_find_timer();
		flags	= UPDATE_TIME;
	}

	delta = current_msec;

	epoll_process_events(cycle, timer, flags);

	delta = current_msec - delta;

	if (delta){
		event_expire_timers();
	}
}

int event_process_init(cycle_t *cycle)
{
	int	m, i;
	char	*shared;
	shm_t	shm;
	size_t	size, cl;
	event_t	*rev, *wev;
	listening_t	*ls;
	connection_t	*c, *next, *old;

	timer_resolution = 100;	// 指定超时检测方案

	if (accept_mutex_ptr)
		return E_OK;

	cl = 128;
	size = cl + cl;

	shm.size = size;
	shm.log = cycle->log;

	if (shm_alloc(&shm) != E_OK){
		fprintf(stderr, "shm_alloc() %s, %d, %s failed.\n", __FILE__, __LINE__, __func__);
		return E_FAIL;
	}

	shared = shm.addr;
	accept_mutex_ptr = (uint32_t*)shared;

	if (shmtx_create(&accept_mutex, shared, lock_file) != E_OK){
		fprintf(stderr, "shm_create() %s, %d, %s failed.\n", __FILE__, __LINE__, __func__);
		return E_FAIL;
	}

	connection_counter_ptr = (uint32_t*)(shared+1*cl);
	*connection_counter_ptr = 1;

	event_timer_init();	
	cycle->connection_n	= 511;

	epoll_init(cycle, timer_resolution);

	if (timer_resolution && !(event_flags & USE_TIMER_EVENT)){
		struct sigaction sa;
		struct itimerval itv;

		memset(&sa, 0, sizeof(struct sigaction));
		sa.sa_handler = timer_signal_handler;
		sigemptyset(&sa.sa_mask);

		if (sigaction(SIGALRM, &sa, NULL) == -1){
			fprintf(stderr, "sigaction() failed.\n");
			return -1;
		}

		itv.it_interval.tv_sec	= timer_resolution / 1000;
		itv.it_interval.tv_usec = (timer_resolution % 1000) *1000;
		itv.it_value.tv_sec	= timer_resolution / 1000;
		itv.it_value.tv_usec = (timer_resolution % 1000) *1000;

		if (setitimer(ITIMER_REAL, &itv, NULL) == -1){
			fprintf(stderr, "setitimer() failed.\n");
		}
	}

	//连接数组
	cycle->connections = malloc(sizeof(connection_t) * cycle->connection_n);
	if (cycle->connections == NULL){
		fprintf(stderr, "cycle->connections malloc failed.\n");
		return -1;
	}
	c = cycle->connections;

	//读事件数组
	cycle->read_events = (event_t *)malloc(sizeof(event_t)*cycle->connection_n);
	if (cycle->read_events == NULL){
		fprintf(stderr, "cycle->read_events malloc failed.\n");
		return -1;
	}
	rev = cycle->read_events;
	for (i=0; i<cycle->connection_n; i++){
		rev[i].closed = 1;
		rev[i].instance = 1;
	}

	//写事件数组
	cycle->write_events = (event_t *)malloc(sizeof(event_t)*cycle->connection_n);
	if (cycle->write_events == NULL){
		fprintf(stderr, "cycle->write_events malloc failed.\n");
		return -1;
	}
	wev = cycle->write_events;
	for (i=0; i<cycle->connection_n; i++){
		wev[i].closed = 1;
	}

	i = cycle->connection_n;
	next = NULL;

	//预先分配的处理连接的基本赋值, 每个连接对应的读写事件
	do {
		i--;
		
		c[i].data = next;
		c[i].read = &cycle->read_events[i];
		c[i].write = &cycle->write_events[i];
		c[i].fd = -1;

		next = &c[i];
		if (next == NULL)
			printf(" next null == i %d\n", i);
	}while(i);

	//空闲连接指向数组头
	cycle->free_connections = next;
	cycle->free_connection_n = cycle->connection_n;

	ls = cycle->listening.elts;

	for (i=0; i<cycle->listening.nelts; i++){
		c = get_connection(ls[i].fd);	//获取一个空闲连接,第一个获取的是next
		if (c == NULL){
			fprintf(stderr, "get_connection failed.\n");
			return -1;
		}
		c->listening = &ls[i];	//逐个取监听队列，这里暂时只有一个listen,并对每个监听初始化对应连接,连接上有读写事件
		ls[i].connection = c;
		
		rev = c->read;	
		rev->accept = 1;
		rev->handler = event_accept;	//读事件处理的回调函数

		if (epoll_add_event(rev, READ_EVENT, 0) == E_FAIL){
			fprintf(stderr, "epoll_add_event(rev) faild\n");
			return E_FAIL;
		}
	}

	return E_OK;
}


int handle_read_event(event_t *rev, int flags)
{
	if (event_flags & USE_CLEAR_EVENT){
		if (!rev->active && !rev->ready){
			if(verbose)	
				printf("%s == %d, %s\n", __FILE__, __LINE__, __func__);
			if (epoll_add_event(rev, READ_EVENT, CLEAR_EVENT) == -1)
				return -1;
		}
			
		return 0;
	}

	return 0;
}

int handle_write_event(event_t *wev, size_t lowat)
{
	if (event_flags & USE_CLEAR_EVENT){
		if (!wev->active && !wev->ready){
			if(verbose)	
				printf("%s == %d, %s\n", __FILE__, __LINE__, __func__);
			if (epoll_add_event(wev, WRITE_EVENT, CLEAR_EVENT ) == -1)
				return -1;

		}

		return 0;
	}

	return 0;
}


